import datetime

from django.http.response import HttpResponse, HttpResponseBadRequest
from django.views.decorators.csrf import csrf_exempt
from wechat_sdk import WechatBasic, WechatConf
from wechat_sdk.exceptions import ParseError
from wechat_sdk.messages import TextMessage

from wzusxjm.models import Member, Attend, Activity, Advice

# -*- coding: utf-8 -*-

WECHAT_TOKEN = 'sxjm'
AppID = 'wx384dc1f5e3afb034'

conf = WechatConf(
    token=WECHAT_TOKEN,
    appid=AppID,
    encrypt_mode='normal',
    appsecret='31da1194c655ffc7861382390e42efb4'
)

# 实例化 WechatBasic
wechat_instance = WechatBasic(
    conf=conf
)


# Create your views here.
class UTC(datetime.tzinfo):
    """UTC"""

    def __init__(self, offset=0):
        self._offset = offset

    def utcoffset(self, dt):
        return datetime.timedelta(hours=self._offset)

    def tzname(self, dt):
        return "UTC +%s" % self._offset

    def dst(self, dt):
        return datetime.timedelta(hours=self._offset)


@csrf_exempt
def index(request):
    if request.method == 'GET':
        # 检验合法性
        # 从 request 中提取基本信息 (signature, timestamp, nonce, xml)
        signature = request.GET.get('signature')
        timestamp = request.GET.get('timestamp')
        nonce = request.GET.get('nonce')

        if not wechat_instance.check_signature(
                signature=signature, timestamp=timestamp, nonce=nonce):
            return HttpResponseBadRequest('Verify Failed')

        return HttpResponse(
            request.GET.get('echostr', ''), content_type="text/plain")

    # 解析本次请求的 XML 数据
    try:
        wechat_instance.parse_data(data=request.body)
    except ParseError:
        return HttpResponseBadRequest('Invalid XML Data')

    # 获取解析好的微信请求信息
    message = wechat_instance.get_message()

    # 关注事件以及不匹配时的默认回复
    response = wechat_instance.response_text(
        content=(
            '请输入学号，绑定后可以查看更多内容'
        ))
    if isinstance(message, TextMessage):
        # 当前会话内容
        member = Member.objects.filter(OpenID=message.source).first()
        content = message.content.strip()
        if member:
            reply_text = actions(content, member)
        else:
            if not content.isdigit():
                reply_text = "学号输入格式不正确，请重新输入"
            else:
                member = Member.objects.filter(SNO=content).first()
                if not member:
                    reply_text = "未找到你的记录，请确认学号输入正确或确认已加入数学建模协会，如果还有问题，请联系管理员"
                elif len(member.OpenID) == 0:
                    member.OpenID = message.source
                    member.save()
                    reply_text = "欢迎 {} 同学！ 绑定成功\n【输入任意内容查看功能提示】".format(member.name)
                else:
                    reply_text = '已被其他微信号绑定'
        response = wechat_instance.response_text(content=reply_text)

    return HttpResponse(response, content_type="application/xml")


def actions(content, member):
    if content == "解绑":
        member.OpenID = ''
        member.save()
        return member.name + " 解绑成功"
    elif content == "活动":
        res = ""
        num = 1
        for activity in Activity.get_now_activity():
            res += "活动{}. \n".format(num) + str(activity)
            res += '\n-----------------------------\n'
            num += 1

            # 检查报名时间
        return res if len(res) else "活动正在策划中，有活动会进行推送，届时请积极参与。"
    elif content.startswith('报名') and content[2:].isdigit():
        index = int(content[2:])
        activitys = list(Activity.get_now_activity())
        if len(activitys) >= index > 0:
            activity = activitys[index - 1]
        else:
            return "活动编号错误"
        return activity.attend(member)
    elif content.startswith('取消') and content[2:].isdigit():
        index = int(content[2:])
        activitys = list(Activity.get_now_activity())
        if len(activitys) >= index > 0:
            activity = activitys[index - 1]
        else:
            return "活动编号错误"
        return activity.unregist(member)
    elif content.startswith('建议') or content.startswith('汇总'):
        advice = Advice()
        advice.user = member
        advice.content = content
        advice.save()
        return "{0}已收录，感谢您提交的{0}".format(content[:2])
    elif content == '查询':
        if member.category >= 50:
            res = ""
            for advice in Advice.get_recent():
                res += str(advice) + '\n-------------------\n'
            return res[:-1] if len(res) else "无建议"
    elif content == '我的活动':
        res = ''
        for attend in Attend.objects.filter(available=True).filter(user=member):
            res += "{} {} ({})\n".format('【确认参与】' if attend.affirm() else '【等待筛选】', attend.activity.name,
                                         Activity.str_time(attend.activity.start_time)) + '\n'
            if attend.affirm():
                # 确认参加，则同时可查看同组组员

                res += "同组组员：\n" + Activity.str_mem(attend.group.members.all()) + '\n--------------------'
        if len(res) == 0:
            return '尚未参加或报名任何活动'
        return res[:-1]
    elif content == "情况":
        if member.category >= 30:
            res = ""
            for activity in Activity.get_now_activity():
                res += activity.name + ':\n'
                if activity.finish_fresh:
                    for g in activity.groups.all():
                        res += activity.str_mem(g.members.all())
                        res += '\n-------------\n'
                else:
                    res += activity.str_mem(activity.now_enroll())
                res += '\n================\n'
            if len(res):
                return res
            return '尚无活动'
    elif content.startwith("擅长"):
        index = int(content[2:])
        if index not in [1, 2, 3]:
            return "请输入标准的内容，如：擅长1"
        member.good = index
        member.save()
        return "成功记录所擅长的方面，这将会在组队和活动匹配中成为参考要素之一"
    res = '回复【解绑】解除绑定\n回复【活动】查看可以报名的活动\n回复【报名n】n编号，对活动n进行报名\n回复【取消n】对取消对活动n的报名\n回复【我的活动】查看活动组队或参与信息\n回复【擅长n' \
          '】将修改个人的擅长方面信息\n以【建议】为开始的内容将会被收录 \n具体的操作说明请查看公众号历史记录中发的 ' \
          '【公众号使用指南】，在使用过程中遇到的任何问题都可以联系会长 '

    if member.category >= 30:
        res += '\n--------------------\n 管理命令：\n【情况】查看活动报名情况'
        if member.category >= 50:
            res += '\n【查询】查看最近一周内收录的建议 '
    return res
